import java.io.IOException;
import java.net.*;
import java.util.concurrent.TimeoutException;


public class pingpong {
	boolean isPing;
	String remoteHost;
	int maxRuns, runs, portListen, portTo;

	DatagramSocket socket;
	InetAddress remote_adr;

	public pingpong(boolean isPing, String remoteHost, int maxRuns) {
		this.isPing = isPing;
		this.maxRuns = maxRuns;
		
		if(isPing) {
			portListen = 5555;
			portTo = 6666;
		}
		else {
			portListen = 6666;
			portTo = 5555;
		}

		try {
			this.remote_adr = InetAddress.getByName(remoteHost);
		} catch (UnknownHostException ex) {
			// maybe do something
		}
	}

	public void start() {
		try {
			socket = new DatagramSocket(portListen);
			socket.setSoTimeout(5000);
			System.out.println("listening port: " + portListen + ", sending to: " +  portTo);
		} catch (SocketException ex) {
			// maybe do something
		}

		String msg = null;
		for(runs = 0; runs < maxRuns; runs++) {
			System.out.println("Loop #" + runs);
			if(isPing) {
				checkMessage(msg);
				UDPsend("ping");
			}

			try {
				msg = UDPreceive();
				System.out.println("Received: " + msg);
			}
			catch(IOException ex) {
				System.out.println("Timeout! Nothing received. Trying again.");
				msg = null;
			}

			
			if(!isPing) {
				checkMessage(msg);
				UDPsend("pong");
			}
		}
	}

	public boolean checkMessage(String msg) {
		if(msg == null)
			return true;
		
		if(msg.equals((isPing) ? "ping" : "pong"))
			return true;
		else
			return false;
	}

	public void UDPsend(String text) {
		byte[] msg = new byte[4];
		try {
			msg = text.getBytes();
			DatagramPacket sender = new DatagramPacket(msg, msg.length, remote_adr, portTo);
			System.out.println("Sending: " + text);
			socket.send(sender);
		}
		catch(Exception e) {
			// do something
		}
	}

	public String UDPreceive() throws IOException {
		byte[] msg = new byte[4];
		DatagramPacket receiver = new DatagramPacket(msg, msg.length);
		socket.receive(receiver);
		return new String(receiver.getData());
	}




	public static void main(String[] args) {
		/*
		 * args[0]: String type, ping or pong
		 * args[1]: String remoteHost
		 * args[2]: int runs
		 */

		pingpong pp = new pingpong(
				(args[0].equals("ping")) ? true : false,
				args[1],
				new Integer(args[2])
			);
		pp.start();
	}
}